#ifndef __EVENTLOOP_H__
#define __EVENTLOOP_H__

#include "MutexLock.h"
#include <vector>
#include <map>
#include <memory>
#include <functional>
#include <sys/epoll.h>

using std::vector;
using std::map;
using std::shared_ptr;

namespace myNameSpace {
class Acceptor;
class TcpConnection;
using TcpConnectionCallback = std::function<void(shared_ptr<TcpConnection>)>;
using TaskCallback = std::function<void()>;

class EventLoop {
public:
    EventLoop(Acceptor &acceptor);
    ~EventLoop();

    void loop();
    void unloop();

    void setNewConnectionCallback(TcpConnectionCallback &&cb);
    void setMessageCallback(TcpConnectionCallback &&cb);
    void setCloseCallback(TcpConnectionCallback &&cb);

    void addSendTaskAndNotify(TaskCallback &&cb);

private:
    int createEpollFd();
    void addEpollReadEvent(int fd);
    void delEpollReadEvent(int fd);
    void waitEpollFd();

    void handleNewConnection();
    void handleMessage(int netFd);

    int createEventFd();
    void setEventFlag();
    void clearEventFlag();
    void doSendTask();
    
private:
    Acceptor &_acceptor;
    int _epollFd;
    int _eventFd;
    vector<struct epoll_event> _eventVector;
    map<int, shared_ptr<TcpConnection>> _tcpConnections;
    MutexLock _mutex;
    vector<TaskCallback> _sendingTasks;
    bool _isLooping;
    TcpConnectionCallback _onNewConnection;
    TcpConnectionCallback _onMessage;
    TcpConnectionCallback _onClose;
};
} // end of namespace myNameSpace

#endif
